﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Interactivity;
using System.Linq;
using System.Collections;

namespace ScrumBoard
{
  public class ChildrenGeneratorBehavior : Behavior<Panel>
  {
    public event EventHandler<ChildrenGeneratorEventArgs> ChildrenGenerating;
    bool generated;
    public DataTemplate ItemTemplate
    {
      get { return (DataTemplate)GetValue(ItemTemplateProperty); }
      set { SetValue(ItemTemplateProperty, value); }
    }
    public static readonly DependencyProperty ItemTemplateProperty = DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(ChildrenGeneratorBehavior), null);


    protected virtual void OnItemsGenerating()
    {
      if (ChildrenGenerating != null)
      {
        var e = new ChildrenGeneratorEventArgs(AssociatedObject);
        ChildrenGenerating(this, e);

        if (e.Items != null) GenerateItems(e.Items);
      }
    }

    protected virtual void GenerateItems(IEnumerable items)
    {
      if (generated) return;
      generated = true;
      foreach (var item in items)
      {
        AssociatedObject.Children.Add(GenerateItem(item));
      }
    }

    public UIElement GenerateItem(object dataContext)
    {
      var element = (UIElement)ItemTemplate.LoadContent();
      if (element is FrameworkElement)
        ((FrameworkElement)element).DataContext = dataContext;
      return element;
    }


    #region not important

    protected override void OnAttached()
    {
      base.OnAttached();
      if (ItemTemplate == null) throw new NullReferenceException("ItemTemplate can not be null in ChildrenGeneratorBehavior");

      if (AssociatedObject.DataContext != null)
        OnItemsGenerating();
      else
        AssociatedObject.DataContextChanged += AssociatedObject_DataContextChanged;
    }

    protected override void OnDetaching()
    {
      AssociatedObject.DataContextChanged -= AssociatedObject_DataContextChanged;
      base.OnDetaching();
    }

    void AssociatedObject_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
     // AssociatedObject.DataContextChanged -= AssociatedObject_DataContextChanged;
      OnItemsGenerating();
    }

    #endregion

  }

  public class ChildrenGeneratorEventArgs : EventArgs
  {
    public Panel Panel { get; private set; }
    public IEnumerable Items { get; set; }

    public ChildrenGeneratorEventArgs(Panel panel)
    {
      Panel = panel;
    }
  }
}
